import stackless
import time
import struct
import sglibrary.reckon as reckon
from sglibrary import Actor, Vector

class World(Actor):
    def __init__(self, players={}):
        self.players = players
        self.actions = {"PJOIN": self.player_join, "DATA": self.data,
                        "OJOIN": self.object_join}
        Actor.__init__(self)
    
    def process_message(self, action, args):
        self.actions[action](*args)

    def data(self, player, data):
        try:
            self.players[player].send("NET", struct.unpack("B", data[0]), data[1:])
        except KeyError:
            print "Possible Cracker ip:%s", player

    def player_join(self, player, channel):
        self.players[player] = channel

    def player_leave(self, player):
        del(self.players[player])

    def object_join(self, channel):
        self.objects.append(channel)
    
    def update(self):
        while True:
            for player in self.players:
                player.update()
            stackless.schedule()


## class Sector(Actor):
##     def __init__(self, players={}, asteroids={}):
##         self.players = players
##         self.asteroids = asteroids
##         self.positons = dict([(key, (0,0,0)) for key in self.players])
##         self.actions = {"set_pos": self.set_positions}
##         Actor.__init__(self)

##     def set_positions(self, player, position):
##         self.positions[player] = position

##     def send_actor_postions(self):
##         for player in self.players:
##             player.send(self.positions)

##     def process_message(self, action, args):
##         self.actions[action](*args)

class Player(Actor):
    def __init__(self, position, up, world, name):
        self.position = position
        self.u = 0
        self.up = up
        self.world = world
        self.name = name
        self.actions = {"shot": self.shot,
                        #"DATA": self.received,
                        "NET": self.user_action}
        self.methods = [self.shot]
        self.last_time = 0
        Actor.__init__(self)
        world.send(("PJOIN", (self.name, self.channel)))

    def process_message(self, action, args):
        self.actions[action](*args)

    def user_action(self, method, data):
        print "user_action", method, data
        self.methods[method](data)

    def dispatch(self, message):
        pass

    def shot(self, position, direction):
        if time.time() > self.last_time:
            Shot(time, position, direction, world)
            self.last_time = time

    def update(self, position):
        v = 1000*(self.position - position)/self.clock.tick()
        self.reckoner = reckon.reckon(self.u, v)
        self.position = position
        self.u = v
    
    def step(self):
        self.reckoner.next()

class Shot(Actor):
    def __init__(self, time, position, direction, world):
        print self, time, position, direction
        self.position = Vector(position)
        self.direction = Vector(direction)
        self.world = world
        Actor.__init__(self)
        world.send("OJOIN", self.channel)

    def set_position(self, rho):
        return self.position + rho * self.direction

class Asteroid(Actor):
    pass
